<?php
/**
 * Handles creation and authentication of web users.
 * 
 * @author Pyranja
 */
class Auth {
	
	private static $entropy = array();
	
	// init entropy array
	public static function init() {
		self::$entropy = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890");
	}
	
	/*
	 * Associates a customer model with a username and password
	 * @returns customer propel object that was associated with webuser -> fluid interface
	 * @throws InvalidArgumentException on bad input
	 */
	public static function update(Customer $customer,$name,$password) {
		self::checkInput($name, $password);
		// check if passed customer valid
		if (isset($customer)) {
			$webuser = $customer->getWebuser();
			if (!isset($webuser)) {
				// create user model
				$webuser = new Webuser();
			}
		} else {
			throw new InvalidArgumentException("customer [$customer] invalid",500);
		}
		// prepare password
		$salt = self::generateSalt();
		$hashedpw = self::mangle($password,$salt);
		$webuser->setUsername($name)
				->setPwhash($hashedpw)
// 				->setSalt($salt)	blowfish combines salt and pw in hash
				->setCustomer($customer)
				->save();
		return $webuser->getCustomer();
	}
	
	/*
	 * Checks the specified credentials against the db
	 * @returns true if credentials valid, false else
	 * @throws InvalidArgumentException on bad input
	 */
	public static function check($name,$password) {
		self::checkInput($name, $password);
		$result = false;
		// load webuser
		$webuser = WebuserQuery::create()->findOneByUsername($name);
		if (isset($webuser)) {
// 			$salt = $webuser->getSalt();
			$origpw = $webuser->getPwhash();
			$hashedpw = self::mangle($password,$origpw);
// 			print "\nFound ".$webuser->getUsername();
// 			print "\nComparing hashed ".$hashedpw." with orig ".$origpw;
			$result = $hashedpw == $origpw;
		}
		return $result;		
	}
	
	protected static function checkInput($name,$password) {
		// check input - call by reference ! trim will not cascade but fails fast on pure whitespace
		$name = trim($name);
		$password = trim($password);
		if (empty($name) || empty($password)) {
			throw new InvalidArgumentException("username [$name] or password [$password] invalid",400);
		}
	}
	
	// generate a random string
	protected static function generateSalt() {
		shuffle(self::$entropy);					// randomize char pool
		$temp = array_slice(self::$entropy, 0,22); 	// first 22 characters
		return "$2a$04$".implode('', $temp); 					// smush them back into a string and append to blowfish salt starter
	}
	
	// hash the specified password with appended salt
	protected static function mangle($pw,$salt) {
		return crypt($pw,$salt);
	}
}
// initialization
Auth::init();
?>